home *** CD-ROM | disk | FTP | other *** search
- /*==============================================================================
-
- FICHERO: ESCALA.C
-
- AUTOR: ANTONIO LADESA JURADO
-
- FECHA: 24/6/94
-
- DESCRIPCION:
-
- Fichero que contiene las estructuras, constantes, variables y funciones
- internas y externas para el escalado de imágenes.
-
- ==============================================================================*/
-
-
- /*---- MODULOS USADOS --------------------------------------------------------*/
-
- #include <stdio.h>
- #include <string.h>
- #include <alloc.h>
-
- #include "global.h"
- #include "memoria.h"
- #include "video.h"
- #include "escala.h"
- #include "error.h"
-
-
- /*---- DEFINICION DE LAS FUNCIONES INTERNAS ----------------------------------*/
-
- char *EscalarLinea(char *linea,int ancho,double factor);
-
- /*---- CODIFICACION DE LAS FUNCIONES OFRECIDAS -------------------------------*/
-
-
- /*---- FUNCION: extern IMAGEN *IMAGENescalar(IMAGEN *c, -------------
- double factorx,
- double factor y)
-
- Descripción:
-
- Esta función escala una imagen usando factores de ancho y alto.
-
- Parámetros:
-
- IMAGEN *c : puntero a estructura que alberga la imagen.
- double factorx : factor de escala a lo ancho.
- double factory : factor de escala a lo alto.
-
- Retorno:
-
- Si se escala, puntero a la nueva imagen.
- Si no, puntero a la imagen original.
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- extern IMAGEN *IMAGENescalar(IMAGEN *c, double factorx,double factory)
- {
- /* buffers para las líneas */
- char buffer[ANCHO_MAXIMO];
- char bufferVGA[ANCHO_MAXIMO];
- /* puntero a nueva imagen */
- IMAGEN *e = NULL;
- /* contadores de línea */
- int i,j,iant,jant;
-
- /* si no existe imagen */
- if(c == NULL)
- {
- ERRORponer(ERRnoImagen);
- return(c);
- }
- /* reservar memoria para la cabecera de trabajo */
- if((e=MEMreservarCAB(e))==NULL)
- {
- ERRORponer(ERRnoMemoria);
- return(c);
- }
- /* calcular dimensiones de la nueva imagen */
- factorx /= 100.0;
- factory /= 100.0;
- e->ancho =(double)(c->ancho)*factorx;
- e->alto = (double)(c->alto)*factory;
- /* ajustar anchos */
- switch(c->modo)
- {
- case VIDEOmono:
- if(e->ancho%2) e->ancho++;
- e->bytes = DePixelsABytes(e->ancho);
- if(e->bytes%2) e->bytes++;
- break;
- case VIDEOega:
- /* el ancho debe ser mútiplo de 8 */
- if(e->ancho%8)
- e->ancho+=(8 - (e->ancho%8));
- e->bytes = DePixelsABytes(e->ancho)*4;
- break;
- case VIDEOvga:
- /* número par de pixels */
- if(e->ancho%2) e->ancho++;
- e->bytes = e->ancho;
- break;
- }
- /* si la imagen resultante es muy grande o muy pequeña */
- if(e->ancho > ANCHO_MAXIMO || e->ancho < 16 || e->alto < 16 )
- {
- ERRORponer(ERRescalar);
- e = MEMliberar(e);
- return(c);
- }
- /* reservar memoria para la imagen */
- if(!MEMreservar(e))
- {
- e =MEMliberar(e);
- ERRORponer(ERRnoMemoria);
- return(c);
- }
- /* cargar cabecera de trabajo */
- if(c->haypaleta)
- memcpy(e->paleta,c->paleta,c->colores*3);
- strcpy(e->nombre,c->nombre);
- e->formato = c->formato;
- e->modo = c->modo;
- e->colores = c->colores;
- e->haypaleta = c->haypaleta;
-
- /* escalar segun el modo de video */
- switch(c->modo)
- {
- case VIDEOmono:
- /* si es una reducción */
- if(c->alto > e->alto)
- for(i=0,jant=1;i<c->alto;++i)
- {
- /* calcular línea destino */
- j = (double)i*factory;
- /* si no es la anterior, reducirla y llevarla a memoria */
- if(j != jant)
- {
- /* leer linea */
- MEMleer(buffer,i,c);
- /* convertir a VGA para escalar */
- MONOaVGA(buffer,bufferVGA,c->ancho);
- /* escalar */
- memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
- /* convertir a monocroma */
- VGAaMONO(bufferVGA,buffer,e->ancho);
- /* escribir linea */
- MEMescribir(buffer,j,e);
- /* actualizar línea anterior */
- jant = j;
- }
- }
- /* si es una ampliación */
- else
- for(j=0,iant=1;j<e->alto;++j)
- {
- /* calcular la línea de origen */
- i=(double)j/factory;
- /* si no es la misma de antes, ampliarla */
- if(i!=iant)
- {
- /* leer linea */
- MEMleer(buffer,i,c);
- /* convertir a VGA para escalarla */
- MONOaVGA(buffer,bufferVGA,c->ancho);
- /* escalar */
- memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
- /* convertir a MONO */
- VGAaMONO(bufferVGA,buffer,e->ancho);
- }
- /* escribir linea en memoria */
- MEMescribir(buffer,j,e);
- /* actualizar línea anterior */
- iant = i;
- }
- break;
-
- case VIDEOega:
- /* si es una reducción */
- if(c->alto > e->alto)
- for(i=0,jant=1;i<c->alto;++i)
- {
- /* calcular línea destino */
- j = (double)i*factory;
- /* si no es la anterior, reducirla y llevarla a memoria */
- if(j != jant)
- {
- /* leer linea */
- MEMleer(buffer,i,c);
- /* convertir a VGA para escalarla */
- EGAaVGA(buffer,bufferVGA,c->ancho);
- /* escalar */
- memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
- /* convertir a EGA */
- VGAaEGA(bufferVGA,buffer,e->ancho);
- /* escribir linea en memoria */
- MEMescribir(buffer,j,e);
- jant = j;
- }
- }
- else
- /* si es una ampliación */
- for(j=0,iant=1;j<e->alto;++j)
- {
- /* calcular línea origen */
- i=(double)j/factory;
- /* si no es la anterior, ampliarla */
- if(i!=iant)
- {
- /* leer linea */
- MEMleer(buffer,i,c);
- /* convertir a VGA */
- EGAaVGA(buffer,bufferVGA,c->ancho);
- /* escalar */
- memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
- /* convertir a EGA */
- VGAaEGA(bufferVGA,buffer,e->ancho);
- }
- /* escribir linea en memoria */
- MEMescribir(buffer,j,e);
- }
- break;
-
- case VIDEOvga:
- /* si es una reducción */
- if(c->alto > e->alto)
- for(i=0,jant = 1;i<c->alto;++i)
- {
- /* calcular línea destino */
- j = (double)i*factory;
- /* si no es la misma de antes, reducirla y llevarla a memoria */
- if(j!=jant)
- {
- /* leer línea */
- MEMleer(bufferVGA,i,c);
- /* escalar */
- memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
- /* escribir línea en memoria */
- MEMescribir(bufferVGA,j,e);
- jant = j;
- }
- }
- else
- /* si es una ampliación */
- for(j=0,iant=1;j<e->alto;++j)
- {
- /* calcular línea origen */
- i=(double)j/factory;
- /* si no es la misma de antes, ampliarla */
- if(i!=iant)
- {
- /* leer linea */
- MEMleer(buffer,i,c);
- /* escalar */
- memcpy(bufferVGA,EscalarLinea(buffer,c->ancho,factorx),e->ancho);
- }
- /* escribir linea en memoria */
- MEMescribir(bufferVGA,j,e);
- iant = i;
- }
- break;
- }
- /* devolver nueva imagen escalada */
- c = MEMliberar(c);
- c = NULL;
- return(e);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- CODIFICACION DE LAS FUNCIONES INTERNAS --------------------------------*/
-
-
- /*---- FUNCION: char *EscalarLinea(char *linea,int ancho,double factor ---------
-
- Descripción:
-
- Esta función amplía o reduce una línea (en formato VGA), usando un factor
- de escala.
-
- Parámetros:
-
- char *linea : puntero a la línea a escalar.
- int ancho : ancho de la línea antes de escalarla.
- double factor: factor de escalado.
-
- Retorno:
-
- Puntero a la línea escalada.
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- char *EscalarLinea(char *linea,int ancho,double factor)
- {
- /* contador de líneas */
- int i;
- /* ancho para ampliación */
- int nuevoancho;
- /* buffer para la línea escalada */
- char escalada[ANCHO_MAXIMO];
-
- memset(escalada,0,ANCHO_MAXIMO);
- /* si es una reducción */
- if(factor < 1.0)
- for(i=0;i < ancho;++i)
- escalada[(double)i*factor] = linea[i];
- /* si es una ampliación */
- else
- {
- nuevoancho = ancho*factor;
- for(i=0;i < nuevoancho;++i)
- escalada[i] = linea[(double)i/factor];
- }
- /* devuelve línea escalada */
- return(escalada);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-